home *** CD-ROM | disk | FTP | other *** search
- Algomath- c Library Release 1.0.5 03.2000
- ------------------- ------------- -------
-
- Algomath is a portable Arithmetic C Library.
- All routines have been thoroughly optimised for speed and efficiency,
- while at the same time portable C. However optional
- fast assembly language alternatives for prime numbers time-critical
- routines are also included, particularly for the popular Intel 80x86
- range of processors. There is no problem to exclude this code,
- -(see COMPILING AND USING ALGOMATH)-
-
- The library is tested with DJGPP v2 C-compiler and the
- pgcc-2.90.23 compiler. Under CYGNUS the egcs-2.91.57 compiler.
- Under VISUALC.
- Although it should work on any other system.
-
- Download the latest release at:
- http://www2.vo.lu/homepages/armand/index.html
-
- You are free to do anything you desire with this code,
- as long as you give credit where credit is due...
-
- For criticism, fixes, suggestions, enhancements, send email to:
-
- Armand Turpel: armandt@unforgettable.com
-
- Patrick Dostert: patrick.dostert@cie.etat.lu
- who helped in optimizing this library
-
-
- INDEX
- -----
-
- 1.FILES IN THIS ARCHIVE
- 2.COMPILING AND USING ALGOMATH
- 3.DESCRIPTION OF THE FUNCTIONS
- 4.HISTORY
- 5.LEGAL AND OTHER STUFF
-
-
- FILES IN THIS ARCHIVE:
- ----------------------
-
- algomath.h
- headerfile
- makefile
- DJGPP makefile
- src/*.*
- library source code
- assembly/src/isprime.asm
- isPrime() assembler source code (nasm)
- assembly/obj/isprime.o
- object code of isPrime()(coff format)
- assembly/obj/isprime.obj
- isprime.obj object code of isPrime()(windows object format)
- Readme.txt
- this file
-
-
- COMPILING AND USING ALGOMATH:
- -----------------------------
-
- Under DJGPP, CYGNUS and VISUALC there should be no problem to compile algomath.
-
- Under VISUALC add the following files to your lib project:
- -all files from the /src directory
- -algomath.h
- -assembly/obj/isprime.obj
-
- For DJGPP or CYGNUS:
- If you have PGCC installed change in the makefile:
- #PGCC = 1
- to
- PGCC = 1
- If you have EGCS (on a pentium) installed change in the makefile:
- #EGCS = 1
- to
- EGCS = 1
- Otherwise disable these two variables:
- #PGCC = 1
- #EGCS = 1
-
- If you dont want to include the assembly
- function(s) in the library, disable in the makefile:
- ASSEMBLY = 1
- to
- #ASSEMBLY = 1
- In order also change in the algomath.h header file:
- #define USE_ISPRIME_ASM
- to
- /*#define USE_ISPRIME_ASM*/
-
- Change to the folder were you have unzip algomath and run make.
- After compiling copy lib/libalgo.a to the djgpp/cygnus lib path
- and algomath.h to the djgpp/cygnus include path.
- To use Algomath, #include <algomath.h> and link with libalgo.a
- Example command line: gcc foobar.c -o foobar.exe -lalgo
-
-
- DESCRIPTION OF THE FUNCTIONS:
- -----------------------------
-
- #######################
- ### Initial Rutines ###
- #######################
-
- int am_init()
- -------------
- The function return 0 if there isn't enough memory else 1.
- You !! MUST !! introduce this function once in your code before you
- use any function.
-
-
- void am_exit()
- -------------
- if you dont need any more the algomath functions in your code, you
- should call this function. It free some memory that algomath use.
-
-
- #######################
- ### Numbers Rutines ###
- #######################
-
- int am_numlength(int n)
- -----------------------
- returns the number of digits of a number.
- am_numlength( 65364785 ) return 8
-
-
- int am_sumdigits(int n)
- -----------------------
- returns the sum of the digits of the number n
- am_sumdigits( 5732 ) returns 17
-
-
- int am_sumdigitsalt(int n)
- --------------------------
- returns the alternating sum of the digits of the number n
- even digitplaces are substracted, odd digitplaces are added
- am_sumdigitsalt( 5732 ) return 1 because 2-3+7-5
-
-
- int am_extract(int n, int x)
- ----------------------------
- returns the digit x you want to extract from a number n.
- a negative number will return a negative result.
- if n > 999999999 then the function return n.
-
- am_extract( 648761, 3) return 7
- am_extract( 648761, 5) return 4
- 0's before the number (00323443) are also considered.
- am_extract( 8761, 6) return 0
-
- if x is negative, the function convert it to positive.
- if x > 9 then only the last digit is considered.
- ex: x=17 so x=7
-
-
- int am_replace(int n, int d1, int d2)
- -----------------------------------
- returns the modified number were n is the
- number to modify, d1 is the digit place to modify and
- d2 the digit to put in.
- if n > 999999999 then the function return n.
- if d1 or d2 is negative, the function convert it to positive.
- if d1 or d2 >9 then only the last digit is considered.
- ex: d1=36 so d1=6
-
- am_replace( 47321, 4, 2) return 42321
- am_replace( 47321, 2, 9) return 47391
- 0's before the number (00323443) are also considered.
- am_replace( 8761, 6, 2) return 208761
-
-
- int am_swap(int n, int d1, int d2)
- ----------------------------------
- return the modified number were n is the number to modify,
- d1 the digit place to swap with the d2 digit place.
- if d1 or d2 is negative, the function convert it to positive.
- if d1 or d2 >9 then only the last digit is considered.
- ex: d1=36 so d1=6
- if n > 999999999 then the function return n.
-
- am_swap( 123456 , 2, 4) return 125436
- am_swap( 123456 , 6, 1) return 623451
- 0's before the number (00323443) are also considered.
- am_swap( 8761, 6, 2) return 608701
-
-
- int am_rotate(int n, int x, int p)
- ----------------------------------
- rotates the digits of a number n, x times, in base 10.
- p is number of digits to rotate.
- if p >9 then only the last digit is considered.
- if n > 999999999 then the function return n.
-
- am_rotate(543210,2,5) returns 105432 ( rotate right if x > 0 )
- am_rotate(543210,-2,5) returns 321054 ( rotate left if x < 0 )
-
- if p > length of the number n then zeros befor the number
- will be included in the rotation process.
- 00543210 = 7 digits
-
- am_rotate(543210,2,7) returns 54321000 ( rotate right if x > 0 )
- am_rotate(543210,-2,7) returns 10005432 ( rotate left if x < 0 )
-
- if p < length of the number n then only the first p digits
- of the number n will be rotated.
-
- am_rotate(543210,2,3) returns 543102 ( rotate right if x > 0 )
- am_rotate(543210,-2,3) returns 543021 ( rotate left if x < 0 )
-
-
- int am_sort( int n)
- -------------------
- " sorts " the digits of a number n
- am_sort( 57834 ) returns 34578
- if n > 999999999 then the function return n.
-
-
- ##########################
- ### Arithmetic Rutines ###
- ##########################
-
- int am_sumdivisor(int n)
- ------------------------
- returns the sum of all possible divisors of the number n,
- n not included
- am_sumdivisors( 20 ) returns 22 ( = 1 + 2 + 4 + 5 + 10 )
-
-
- int am_gcd(int a, int b)
- ------------------------
- returns the " greatest common divisor " of two numbers a and b
- am_gcd( 123698745, 147896325) returns 45
-
- int am_hailstone(int n)
- -----------------------
- This function allows you to investigate hailstone numbers:
- if n == odd then it return n*3+1
- if n== even then it return n/2
- call this function until it return 1.
- if n is negative <0 then the result is also negative.
- if the result is bigger than int or n=0, it return 0 (failure).
- n=77671 is the first number that return 0.
- if you want to investigate all big numbers,I recommend you to use the
- c/c++ miracl library:
- ftp://ftp.compapp.dcu.ie/pub/crypto/miracl.zip
-
- ex.:
-
- n=25267;
- while(n!=1){
- n=am_hailstone(n);
- if(n==0){
- printf("n is to big\n");
- exit();
- }
- printf("%d\n",n);
- }
-
- #############################
- ### Prime Numbers Rutines ###
- #############################
-
- int am_isprime(int n)
- ---------------------
- returns 1 if n is prime else 0
- negative numbers n are also accepted.
-
- int am_prime_ba(int t, int x)
- -----------------------------
- If x<0 then the function return the next prime number "befor" the number t.
- If x>0 then the function return the next prime number "after" the number t.
- If x==0 then the function return t
- If t is negative then the result will also be negative.
-
- int *am_primes_array(int n, int x)
- ----------------------------------
- create x prime numbers from a given number n, and return the
- pointer address. return 0 if there isnt enough memory.
- if n is negative then the primes are also negative.
-
- ex:
- int *pointer , c=0;
-
- if((pointer = am_primes_array(4, 3)) == NULL)
- printf("not enough memory\n");
-
- while( *(pointer+c)){
- printf("%d\n",*(pointer+c));
- c++;
- }
-
- return *(pointer+0)=5 *(pointer+1)=7 *(pointer+2)=11
- *(pointer+3)=0 !! last variable is always 0 !!
-
- WARNING!!!!!!!
- --------------
- If you dont need any more the prime_array result you should free
- the pointer allocation(s):
- free ( pointer );
-
- take a look at the following code:
-
- for(x=0;x<100000;x++){
- pointer=am_prime_array(x, 1000);
- /*do some stuff*/
- }
-
- this allocate 100000*1000 int memory!!!!
- so the correct code should be:
-
- for(x=0;x<100000;x++){
- pointer=am_prime_array(x, 1000);
- /*do some stuff*/
- free(pointer);
- }
-
-
- int *am_primes_between(int n1, int n2, int *p)
- --------------------------------------
- create prime numbers between two given number n1 and n2, and
- return the pointer address. Store in p the number of primes found.
- return 0 if there isnt enough memory.
- if n1 or n2 = negative then the function convert it to positive.
- It dosen't matter whether n1>n2 or n1<n2.
-
- ex:
- int *pointer, p, c=0;
-
- if((pointer = am_primes_between(4, 15, &p)) == NULL)
- printf("not enough memory\n");
-
- while( *(pointer+c)){
- printf("%d\n",*(pointer+c));
- c++;
- }
-
- printf("%d primes found\n", p); print out how many primes found.
-
- print out: 5 7 11 13
- *(pointer+4)=0 !! last last variable is always 0 !!
-
- See WARNING!!!! in am_primes_array()
-
-
- int *am_factorize(int n, int *factors)
- --------------------------------------
- facrorize a number n and return the pointer address were you
- can find the result. factors contains the number of
- how many factors found. return 0 if there isnt enough memory.
- negative numbers n are also accepted.
-
- pointer = am_factorize( 20 , &factors) returns:
- factors = 3
- *(pointer+0)=2, *(pointer+1)=2, *(pointer+2) = 5
- *(pointer+3) = 0 !! last variable is always 0 !!
-
- ex:
-
- int *pointer;
- int factors, x = 0;
-
- if((pointer = am_factorize( 20, &factors ))==NULL){
- printf("not enough memory\n");
- exit(0);
- }
- printf("how many factors found: %d\n",factors);
- while(*(pointer+x)){
- printf("%d\n",*(pointer+x);
- x++;
- }
-
- See WARNING!!!! in am_primes_array()
-
-
- int am_goldbach(int n,int *d1, int *d2)
- --------------------------------------
- "--'strong' Goldbach's Conjecture
- The Conjecture is, "Every even integer >= 4 is the sum of
- two primes.--"
- Return 0 if n not even else 1.
- n is the even number to test.
- after calling the function, d1 contain the smallest possible prime
- and d2 the second greater prime. if n is negative then d1 and d2 are
- also negative.
-
- ex:
-
- int d1,d2,r,n=16;
-
- r = am_goldbach( 16, &d1, &d2);
- printf("%d = %d + %d\n",n,d1,d2);
-
-
- int am_isPrime(unsigned int testnumber)
- ------------------------------
- This is the assembly implementation of am_isprime(int n).
- returns 1 if testnumber is prime else 0
- (optimized by Patrick Dostert: patrick.dostert@cie.etat.lu)
-
- If algomath is compiled with #define AM_ISPRIME_ASM
- then algomath use this function for every prime operation.
- But you can include this function as stand alone in your code.
- declare first: extern int am_isPrime(unsigned int);
- and link isprime.o to your program.
-
- -----------------------------------------------------------------------
-
- HISTORY:
- --------
-
- Algomath
- 0.9 beta first release 12.1997
- 0.91 beta bugfix release 3.1998
- 0.92 beta bugfix release 3.1998
- 0.93 beta reviewed and add int am_goldbach(int a,int *p) 4.1998
- 1.00 beta rewrite of the prime related routines (better performance) 10.1998
- 1.0.1 beta rewrite of the prime related routines
- am_primearray(1,1000000,array)
- 1.0.2 beta optimized am_primearray()
- 1.0.3 beta add am_prime_init
- 1.0.4 complete rewrite the most part of the functions. 11.1999
- fixed some bugs.
- NEW functions:
- am_exit()
- am_isPrime()
- am_numlength()
- am_swap()
- am_replace()
- am_extract()
- am_primes_between()
- 1.0.5 Tested under CYGNUS and VISUALC
- therefor making some change in the makefile
- add am_isprimeba(int n, int x)
- add am_hailstone(int n)
-
-
- LEGAL AND OTHER STUFF:
- ----------------------
-
- Pentium is a (registered) trademark of Intel, http://www.intel.com
- DJGPP is the MSDOS-port of the famous GNU-C compiler, http://www.delorie.com
- MSDOS is a (registered) trademark of Microsoft, http://www.microsoft.com
- for info on GNU software see http://www.gnu.org
-
-
- ------------------------------------------------------------------------------
-
- Luxembourg, 11.1999,
- Armand Turpel